<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<jsp:include page="common/auth.jsp" />
<jsp:include page="common/header.jsp" />

<%@ page language="java" import="java.sql.*"%>
<%@ page language="java" import="java.util.ArrayList"%>
<%@ page language="java" import="java.util.LinkedList"%>
<%@ page language="java" import="java.util.HashSet"%>
<%@ page language="java" import="java.util.Iterator"%>
<%@ page language="java" import="java.util.Date"%>
<%@ page language="java" import="java.util.Calendar"%>
<%@ page language="java" import="db.Config"%>
<%@ page language="java" import="db.Change"%>
<%@ page language="java" import="db.Activity"%>
<%-- -------- Open Connection Code -------- --%>
<%
	final String save = "Save";
	final String pay = "Pay";
	final String receipt = "Receipt";
	final String cancel = "Cancel";
	final String checkout = "Checkout";

	final String welcomeMessage = "welcome to your shopping cart";
	final String confirmMessage = "please confirm what you want to buy";
	final String receiptMessage = "thank you for your payment, here is your receipt";

	String quarterArray[] = {"spring", "spring", "spring", "summer",
			"summer", "summer", "fall", "fall", "fall", "winter",
			"winter", "winter"};

	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;

	String greetingMessage = welcomeMessage;
	String receiptStr = "";

	String stateFlag = save;
  if (request.getParameter("stateFlag") != null) {
    stateFlag = request.getParameter("stateFlag");
  }

  System.out.println("current state: " + stateFlag);

  //get the month as integer
  Date date = new Date();
  Calendar cal = Calendar.getInstance();
  cal.setTime(date);
  int month = cal.get(Calendar.MONTH);

  // get the username from session
  String username = (String) session.getAttribute("username");
  String userid = (String) session.getAttribute("userid");
  String userState = (String) session.getAttribute("userState");

  // get actions
  String saveAction = request.getParameter("Save");
  String checkoutAction = request.getParameter("Checkout");
  String payAction = request.getParameter("Pay");
  String cancelAction = request.getParameter("Cancel");
  String action = request.getParameter("action");

  System.out.println(saveAction);
  System.out.println(checkoutAction);
  System.out.println(payAction);
  System.out.println(cancelAction);

  // set display parameters
  String checkType = "submit";
  String payType = "hidden";
  String creditLabel = "display:none";
  String creditInput = "hidden";
  String disable = "";

	try {
		// Load JDBC Driver class file
		Class.forName(Config.jdbcDriver);

		// Open a connection to the database using DriverManager
		conn = DriverManager.getConnection(Config.connectionURL,
				Config.username, Config.password);
    
		if (action != null && action.equals("addToCart")) {
			
			
			String productId = request.getParameter("productId");
			float price = Float.parseFloat(request.getParameter("price"));

      pstmt = conn.prepareStatement(
        "UPDATE `order` SET amount = amount + 1, total = total + ? " +
        "WHERE product = ? AND user = ? AND state = 'in_cart'");
      pstmt.setDouble(1, price);
      pstmt.setString(2, productId);
      pstmt.setString(3, userid);
      int rowCount = pstmt.executeUpdate();
      
      System.out.println("[addToCart] rowCount: " + rowCount);
      
      if (rowCount == 0) {
        //out.println("<h1>point 4</h1>");

        // insert into the table the newly added order
        pstmt = conn.prepareStatement(
          "INSERT INTO `order` (product, user, amount, state, total, `date`, quarter) " + 
          "VALUES (?, ?, 1, 'in_cart', ?, ?, ?)");
        pstmt.setString(1, productId);
        pstmt.setString(2, userid);
        //amount is 1 so directly give the price to the query
        pstmt.setDouble(3, price);
        pstmt.setDate(4, new java.sql.Date(date.getTime()));
        pstmt.setString(5, quarterArray[month]);
        rowCount = pstmt.executeUpdate();
      }
			//out.println("<h1>point 5</h1>");
			// Commit transaction	
			//no need to use transaction here, since there is only one query
			//conn.commit();
			//no need to use transaction here, since there is only one query
			//conn.setAutoCommit(true);
			stateFlag = save;
			System.out.println(stateFlag);
		}
		//out.println("<h1>point 6</h1>");
		//out.println("<h1>" + stateFlag + "</h1>");

		// if the action is submit, 
    conn.setAutoCommit(false);
    if ((checkoutAction != null && !stateFlag.equals(pay)) || 
        (stateFlag.equals(save) && saveAction != null && saveAction.equals(save))) {

      System.out.println("action: " + save);

      // find out all the products the user has added to his cart
      pstmt = conn.prepareStatement(
        "SELECT product, price FROM `order`, product " + 
        "WHERE `order`.user = ? AND `order`.product = product.id AND `order`.state = 'in_cart'");
      pstmt.setString(1, userid);
      ResultSet productResultSet = pstmt.executeQuery();

      // update all the product amount of the order
      while (productResultSet.next()) {
        String pid = productResultSet.getString("product");
        Float pprice = productResultSet.getFloat("price");
        
        String pamountStr = request.getParameter(pid);
        int pamount = 0;
        try {
          pamount = Integer.parseInt(pamountStr);
        } catch (Exception e) {
          //should be some sort of conversion exception
          e.printStackTrace();
        }
        //out.println("Debug::pamount:" + pamount);

        // if the amount is smaller or equal to 0, that means the 
        if (pamount <= 0) {
          pstmt = conn.prepareStatement(
            "DELETE FROM `order` " + 
            "WHERE `order`.user = ? AND `order`.product = ? AND `order`.state = 'in_cart'");
          pstmt.setString(1, userid);
          pstmt.setString(2, pid);
        } else {
          pstmt = conn.prepareStatement(
            "UPDATE `order` SET amount = ?, total = ? " + 
            "WHERE product = ? AND user = ? AND state='in_cart'");
          pstmt.setInt(1, pamount);
          pstmt.setDouble(2, pamount * pprice);
          pstmt.setString(3, pid);
          pstmt.setString(4, userid); 
        }
        int rowCount = pstmt.executeUpdate();
        //out.println("Debug:" + rowCount);
      }
      stateFlag = save;
      payType = "hidden";
      checkType = "submit";
      greetingMessage = welcomeMessage;

      if (checkoutAction != null && checkoutAction.equals(checkout)) {
        System.out.println("action: " + checkout);
        stateFlag = pay;
        payType = "submit";
        checkType = "hidden";
        creditLabel = "";
        creditInput = "text";
        disable = "disabled";
        greetingMessage = confirmMessage;
      }
    } else if (stateFlag.equals(pay) && payAction != null && payAction.equals(pay)) {
      System.out.println("action: " + payAction);
      pstmt = conn.prepareStatement(
        "SELECT product.name pname, product.price pprice, `order`.amount amount, category.name cname " +
        "FROM `order`, product, category " +
        "WHERE `order`.user = ? AND " +
        "`order`.state = 'in_cart' AND product.ID = `order`.product AND product.category = category.id");
      pstmt.setString(1, userid);
      ResultSet boughtResultSet = pstmt.executeQuery();

      // update all the product amount of the order
      float sumTotal = 0;
      while (boughtResultSet.next()) {
        String pname = boughtResultSet.getString("pname");
        String category = boughtResultSet.getString("cname");
        float pprice = boughtResultSet.getFloat("pprice");
        int pamount = boughtResultSet.getInt("amount");
        receiptStr += ("" + pamount + " " + pname + " with $" + (pprice * pamount) + "</br>");
        sumTotal += pprice * pamount;

        // update dashborad queue 
        if (application.getAttribute("activeUsers") != null) {
          HashSet<String> activeUsers = (HashSet<String>) application.getAttribute("activeUsers");
          for (Iterator<String> i = activeUsers.iterator(); i.hasNext();) {
            String user = i.next();
            if (application.getAttribute(user) != null) {
              Activity activity = (Activity) application.getAttribute(user);

              if (new Date().getTime() - activity.lastVisited.getTime() > 2000) {
                System.out.println("no active user: " + user);
                i.remove();
              } else {
                System.out.println("active user: " + user + " last visited at: " + activity.lastVisited);
              }
              LinkedList<Change> updates = activity.updates;
              updates.add(new Change(userState, category, pamount));
            } else {
              System.out.println("no such user: " + user);
            }
          }
        } else {
          application.setAttribute("activeUsers", new HashSet<String> ());
        }
      }
      receiptStr += ("Total:" + sumTotal + "</br>");

      System.out.println(greetingMessage);

      // set all the state of the items to done
      pstmt = conn.prepareStatement(
        "UPDATE `order`, user " +
        "SET `order`.state = 'done', `order`.`date` = ? " +
        "WHERE `order`.user = ? AND `order`.state = 'in_cart'");
      pstmt.setDate(1, new java.sql.Date(date.getTime()));
      pstmt.setString(2, userid);
      int countDone = pstmt.executeUpdate();
      
      stateFlag = receipt;
      payType = "hidden";
      checkType = "hidden";
      greetingMessage = receiptMessage;

    } else if (cancelAction != null && cancelAction.equals(cancel)) {
      stateFlag = save;
      payType = "hidden";
      checkType = "submit";
      creditLabel = "display:none";
      creditInput = "hidden";
      disable = "";
      greetingMessage = welcomeMessage;
    } else {}
    
    // Commit transaction	
    conn.commit();

    conn.setAutoCommit(true);
%>

<body>
	<div class="container-fluid">
		<div class="row-fluid">
			<div class="span12">
				<h4 class="TopWelcome span7">
					Hi
					<%=username%>,
					<%=greetingMessage%>:
				</h4>
				<%
					pstmt = conn.prepareStatement(
            "SELECT product.id, product.name, product.price, `order`.amount " +
            "FROM `order`, product " +
            "WHERE `order`.user = ? AND `order`.product = product.id AND `order`.state = 'in_cart'");
          pstmt.setString(1, userid);
          ResultSet result = pstmt.executeQuery();

          float sum = 0;

          if (result.next()) {
				%>
				<form action="cart.jsp" method="post">
          <input type="hidden" name="stateFlag" value="<%= stateFlag %>" />
					<table class="MiddleData table table-hover">
						<tr>
							<th>Product Name</th>
							<th>Product Price</th>
							<th>Amount</th>
							<%
								if (stateFlag != null && (stateFlag.equals(pay) || stateFlag.equals(receipt))) {
							%>
							<th>Price</th>
							<%
								}
							%>
						</tr>
						<%
							do {
                int pid = result.getInt("product.id");
                String pname = result.getString("product.name");
                float pprice = result.getFloat("product.price");
                int pamount = result.getInt("order.amount");
						%>
						<tr>
							<input id="stateAction" type="hidden" value=<%=stateFlag%> name="action" />
							<td><%=pname%></td>
							<td>$<%=pprice%></td>
              <td>
                <input class="input-mini" type="text" name="<%=pid%>" id="ProductAmount" value="<%=pamount%>" <%=disable%> />
              </td>
							<%
								if (stateFlag.equals(pay) || stateFlag.equals(receipt)) {
							%>
							<td>$<%=pprice * pamount%></td>
							<%
								}
							%>
						</tr>
						<%
                sum += pprice * pamount;
              } while (result.next());

						%>
					</table>

					<div class="span12">
            <label class="span2" style=<%=creditLabel%>>Credit Card:</label>
            <input class="span4" type=<%=creditInput%> placeholder="XXXX-XXXX-XXXX-XXXX" />
            <label class="span4 offset8">Total Price: <%=sum%></label>
					</div>

					<div class="BottomButtons span4 offset8">
            <input class="btn btn-primary" type=<%=checkType%> name="Checkout" value="Checkout" />
            <input class="btn btn-primary" type=<%=checkType%> name="Save" value="Save" /> 
            <input class="btn btn-primary" type=<%=payType%> id="Pay" name="Pay" value="Pay" />
            <input class="btn btn-warning" type=<%=payType%> name="Cancel" value="Cancel" />
					</div>
				</form>
				<%
					} else if (stateFlag != null && stateFlag.equals(receipt)) {
				%>
				<p class="span12"><%=receiptStr%></p>
				<%
            stateFlag = save;
            payType = "hidden";
            checkType = "submit";
            greetingMessage = welcomeMessage;
            //just finished payment, display thank you message
          } else {
				%>
				<h5 class="span8 offset4">Your shopping cart is empty, go grab
					something!</h5>
				<%
          }
				%>
			</div>

		</div>
	</div>
	<script src="js/jquery-1.9.1.js"></script>
	<script src="js/bootstrap.min.js"></script>
	<script>
		$(document)
				.ready(
						//ask for comfirmation of payment
						function() {
							$("#Pay")
									.click(
											function() {
												return confirm("Are you sure you want to pay the bill and checkout?");
											});
						});
	</script>
</body>
</html>

<%-- -------- Close Connection Code -------- --%>
<%
	// Close the ResultSet
  if (rs != null) {
    rs.close();
  }
		// Close the Statement
		pstmt.close();
		// Close the Connection
		conn.close();
	} catch (SQLException e) {

		//out.println("Caught SQLException");
		// Wrap the SQL exception in a runtime exception to propagate
		// it upwards
		//throw new RuntimeException(e);
	} catch (NullPointerException e) {
		// rs or pstmt are null, no worries
		//out.println("Caught Null Pointer Exception");
		e.printStackTrace();
	} catch (Exception e) {
		out.println("Caught unknown exception!");
		e.printStackTrace();
	} finally {
		// Release resources in a finally block in reverse-order of
		// their creation

		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
			} // Ignore
			rs = null;
		}
		if (pstmt != null) {
			try {
				pstmt.close();
			} catch (SQLException e) {
			} // Ignore
			pstmt = null;
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
			} // Ignore
			conn = null;
		}
	}
%>
